package org.example.ding.service;

import org.example.ding.dto.NutritionProgressDto;
import org.example.ding.entity.Dish;
import org.example.ding.entity.OrderRecord;
import org.example.ding.entity.User;
import org.example.ding.model.DailyNutritionSummary;
import org.example.ding.model.NutritionAlert;
import org.example.ding.repository.DishRepository;
import org.example.ding.repository.OrderRecordRepository;
import org.example.ding.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 简化的营养服务
 * 直接从OrderRecord计算营养数据，不使用复杂的汇总表
 */
@Service
public class NutritionService {

    @Autowired
    private OrderRecordRepository orderRecordRepository;

    @Autowired
    private DishRepository dishRepository;

    @Autowired
    private UserRepository userRepository;

    /**
     * 获取用户今日营养摄入
     */
    public NutritionProgressDto getTodayNutrition(User user) {
        LocalDate today = LocalDate.now();
        List<OrderRecord> todayOrders = orderRecordRepository.findByUserAndOrderDate(user, today);
        
        System.out.println("用户 " + user.getUsername() + " 今日订单数量: " + todayOrders.size());
        
        BigDecimal totalCalories = BigDecimal.ZERO;
        BigDecimal totalProtein = BigDecimal.ZERO;
        BigDecimal totalCarbs = BigDecimal.ZERO;
        BigDecimal totalFat = BigDecimal.ZERO;
        
        for (OrderRecord order : todayOrders) {
            if (order.getActualCalories() != null) {
                totalCalories = totalCalories.add(order.getActualCalories());
            }
            if (order.getActualProtein() != null) {
                totalProtein = totalProtein.add(order.getActualProtein());
            }
            if (order.getActualCarbs() != null) {
                totalCarbs = totalCarbs.add(order.getActualCarbs());
            }
            if (order.getActualFat() != null) {
                totalFat = totalFat.add(order.getActualFat());
            }
            
            System.out.println("订单: " + order.getDish().getName() + 
                             " - 卡路里: " + order.getActualCalories() + 
                             ", 蛋白质: " + order.getActualProtein() +
                             ", 碳水: " + order.getActualCarbs() + 
                             ", 脂肪: " + order.getActualFat());
        }
        
        System.out.println("今日总营养 - 卡路里: " + totalCalories + 
                         ", 蛋白质: " + totalProtein +
                         ", 碳水: " + totalCarbs + 
                         ", 脂肪: " + totalFat);
        
        // 构建返回结果
        return new NutritionProgressDto(
            totalCalories,
            totalProtein,
            totalCarbs,
            totalFat,
            user.getDailyCaloriesGoal() != null ? user.getDailyCaloriesGoal() : BigDecimal.valueOf(2000),
            user.getDailyProteinGoal() != null ? user.getDailyProteinGoal() : BigDecimal.valueOf(150),
            user.getDailyCarbsGoal() != null ? user.getDailyCarbsGoal() : BigDecimal.valueOf(250),
            user.getDailyFatGoal() != null ? user.getDailyFatGoal() : BigDecimal.valueOf(65)
        );
    }

    /**
     * 获取用户指定日期的营养摄入
     */
    public Map<String, Object> getNutritionByDate(User user, LocalDate date) {
        List<OrderRecord> orders = orderRecordRepository.findByUserAndOrderDate(user, date);
        
        BigDecimal totalCalories = BigDecimal.ZERO;
        BigDecimal totalProtein = BigDecimal.ZERO;
        BigDecimal totalCarbs = BigDecimal.ZERO;
        BigDecimal totalFat = BigDecimal.ZERO;
        
        for (OrderRecord order : orders) {
            if (order.getActualCalories() != null) {
                totalCalories = totalCalories.add(order.getActualCalories());
            }
            if (order.getActualProtein() != null) {
                totalProtein = totalProtein.add(order.getActualProtein());
            }
            if (order.getActualCarbs() != null) {
                totalCarbs = totalCarbs.add(order.getActualCarbs());
            }
            if (order.getActualFat() != null) {
                totalFat = totalFat.add(order.getActualFat());
            }
        }
        
        Map<String, Object> nutrition = new HashMap<>();
        nutrition.put("calories", totalCalories.doubleValue());
        nutrition.put("protein", totalProtein.doubleValue());
        nutrition.put("carbs", totalCarbs.doubleValue());
        nutrition.put("fat", totalFat.doubleValue());
        nutrition.put("date", date.toString());
        
        return nutrition;
    }

    /**
     * 获取用户今日订单记录
     */
    public List<OrderRecord> getTodayOrders(Long userId) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        LocalDate today = LocalDate.now();
        return orderRecordRepository.findByUserAndOrderDate(user, today);
    }

    /**
     * 记录单个点餐
     */
    public OrderRecord recordOrder(Long userId, Long dishId, OrderRecord.MealType mealType, BigDecimal portionSize) {
        System.out.println("开始记录点餐 - 用户ID: " + userId + ", 菜品ID: " + dishId + ", 餐别: " + mealType + ", 份量: " + portionSize);

        // 获取用户
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        // 获取菜品
        Dish dish = dishRepository.findById(dishId)
                .orElseThrow(() -> new RuntimeException("菜品不存在"));

        System.out.println("用户: " + user.getUsername() + ", 菜品: " + dish.getName());

        // 创建订单记录
        OrderRecord orderRecord = new OrderRecord(user, dish, mealType, portionSize);

        // 保存订单
        OrderRecord savedOrder = orderRecordRepository.save(orderRecord);

        System.out.println("点餐记录保存成功 - 订单ID: " + savedOrder.getId() +
                         ", 实际卡路里: " + savedOrder.getActualCalories());

        return savedOrder;
    }

    /**
     * 批量记录点餐
     */
    public List<OrderRecord> recordOrders(Long userId, List<OrderRequest> orderRequests) {
        List<OrderRecord> orderRecords = new ArrayList<>();

        for (OrderRequest request : orderRequests) {
            OrderRecord orderRecord = recordOrder(userId, request.getDishId(),
                    OrderRecord.MealType.valueOf(request.getMealType()), request.getPortionSize());
            orderRecords.add(orderRecord);
        }

        return orderRecords;
    }

    /**
     * 订单请求DTO
     */
    public static class OrderRequest {
        private Long dishId;
        private String mealType;
        private BigDecimal portionSize;

        public OrderRequest() {}

        public OrderRequest(Long dishId, String mealType, BigDecimal portionSize) {
            this.dishId = dishId;
            this.mealType = mealType;
            this.portionSize = portionSize;
        }

        public Long getDishId() {
            return dishId;
        }

        public void setDishId(Long dishId) {
            this.dishId = dishId;
        }

        public String getMealType() {
            return mealType;
        }

        public void setMealType(String mealType) {
            this.mealType = mealType;
        }

        public BigDecimal getPortionSize() {
            return portionSize;
        }

        public void setPortionSize(BigDecimal portionSize) {
            this.portionSize = portionSize;
        }
    }

    /**
     * 获取指定日期的营养摄入汇总
     */
    public DailyNutritionSummary getDailyNutrition(Long userId, LocalDate date) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        List<OrderRecord> orders = orderRecordRepository.findByUserAndOrderDate(user, date);

        BigDecimal totalCalories = BigDecimal.ZERO;
        BigDecimal totalProtein = BigDecimal.ZERO;
        BigDecimal totalCarbs = BigDecimal.ZERO;
        BigDecimal totalFat = BigDecimal.ZERO;

        for (OrderRecord order : orders) {
            if (order.getActualCalories() != null) {
                totalCalories = totalCalories.add(order.getActualCalories());
            }
            if (order.getActualProtein() != null) {
                totalProtein = totalProtein.add(order.getActualProtein());
            }
            if (order.getActualCarbs() != null) {
                totalCarbs = totalCarbs.add(order.getActualCarbs());
            }
            if (order.getActualFat() != null) {
                totalFat = totalFat.add(order.getActualFat());
            }
        }

        return new DailyNutritionSummary(date, totalCalories, totalProtein, totalCarbs, totalFat);
    }

    /**
     * 检查营养摄入是否超标或不足
     */
    @Transactional(readOnly = true)
    public NutritionAlert checkNutritionAlert(Long userId, LocalDate date) {
        User user = userRepository.findById(userId)
            .orElseThrow(() -> new RuntimeException("用户不存在"));

        DailyNutritionSummary summary = getDailyNutrition(userId, date);

        return new NutritionAlert(user, summary);
    }
}
